﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using System.Text;
using System.Threading;
using System.Net;
using System.IO;
using System;


namespace KFGame
{

    public class RequestState
    {
        const int m_buffetSize = 1024;
        public StringBuilder m_requestData;
        public byte[] m_bufferRead;
        public HttpWebRequest m_request;
        public HttpWebResponse m_response;
        public Stream m_streamResponse;

        public RequestState()
        {
            m_bufferRead = new byte[m_buffetSize];
            m_requestData = new StringBuilder("");
            m_request = null;
            m_streamResponse = null;
        }

    }
    public class NetWork
    {


        public delegate void Event(string tag, string url, int id, string message);

        public Event doEvnet;
        private Thread sendThread;

        public void init()
        {

            // sendThread = new Thread(checkNet);
            // sendThread.IsBackground = true;
            //  sendThread.Start();
        }

        public bool checkNet()
        {
            UnityWebRequest webRequest = UnityWebRequest.Get("http://www.baidu.com");

            webRequest.SendWebRequest();
            //异常处理，很多博文用了error!=null这是错误的，请看下文其他属性部分

            if (webRequest.isHttpError || webRequest.isNetworkError)
            {

                // if (doEvnet != null)
                //     doEvnet("test", 404, webRequest.error);

                return false;
            }
            return true;

            // if (doEvnet != null)
            //    doEvnet("test", 200, webRequest.downloadHandler.text);

        }

        public string Get(string host, WWWForm form)
        {

            UnityWebRequest webRequest = UnityWebRequest.Get(host);
            webRequest.SendWebRequest();

            //异常处理，很多博文用了error!=null这是错误的，请看下文其他属性部分
            if (webRequest.isHttpError || webRequest.isNetworkError)
                return webRequest.error;

            return webRequest.downloadHandler.text;
        }

        public IEnumerator GetRequest(string tag, string url, WWWForm methodName = null, Dictionary<string, string> requestHeader = null)
        {

            using (UnityWebRequest webRequest = UnityWebRequest.Get(url))
            {
                //设置header
                if (requestHeader != null)
                    foreach (var v in requestHeader)
                        webRequest.SetRequestHeader(v.Key, v.Value);

                yield return webRequest.SendWebRequest();

                if (webRequest.isHttpError || webRequest.isNetworkError)
                {
                    if (doEvnet != null)
                        doEvnet(tag, url, 404, webRequest.error);

                }
                else
                {
                    if (doEvnet != null)
                        doEvnet(tag, url, 200, webRequest.downloadHandler.text);

                }
            }
        }

        public IEnumerator PostRequest(string tag, string url, WWWForm form = null, Dictionary<string, string> requestHeader = null)
        {
            using (UnityWebRequest webRequest = UnityWebRequest.Post(url, form))
            {
                //设置header
                if (requestHeader != null)
                    foreach (var v in requestHeader)
                        webRequest.SetRequestHeader(v.Key, v.Value);

                yield return webRequest.SendWebRequest();



                if (webRequest.isHttpError || webRequest.isNetworkError)
                {
                    if (doEvnet != null)
                        doEvnet(tag, url, 404, webRequest.error);

                }
                else
                {
                    if (doEvnet != null)
                        doEvnet(tag, url, 200, webRequest.downloadHandler.text);

                }
            }
        }


        public string Post(string host, WWWForm form)
        {
            UnityWebRequest webRequest = UnityWebRequest.Post(host, form);
            webRequest.SendWebRequest();
            Debug.Log(webRequest.error);
            //异常处理，很多博文用了error!=null这是错误的，请看下文其他属性部分
            if (webRequest.isHttpError || webRequest.isNetworkError)
                return webRequest.error;

            return webRequest.downloadHandler.text;
        }



        public void ac(string url)
        {

            try
            {

                HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url);

                RequestState myRequestState = new RequestState();
                myRequestState.m_request = myHttpWebRequest;

                Debug.Log("BeginGetResponse Start");
                //异步获取;
                IAsyncResult result = (IAsyncResult)myHttpWebRequest.BeginGetResponse(new AsyncCallback(RespCallback), myRequestState);



                Debug.Log("BeginGetResponse End");
            }
            catch (System.Exception ex)
            {
                Debug.LogError(ex.ToString());
            }

        }
        void RespCallback(IAsyncResult result)
        {


            try
            {
                RequestState myRequestState = (RequestState)result.AsyncState;
                HttpWebRequest myHttpWebRequest = myRequestState.m_request;


                myRequestState.m_response = (HttpWebResponse)myHttpWebRequest.EndGetResponse(result);

                Stream responseStream = myRequestState.m_response.GetResponseStream();
                myRequestState.m_streamResponse = responseStream;

                //开始读取数据;
                IAsyncResult asyncreadresult = responseStream.BeginRead(myRequestState.m_bufferRead, 0, 1024, new AsyncCallback(ReadCallBack), myRequestState);



                return;
            }
            catch (System.Exception ex)
            {
                Debug.LogError(ex.ToString());
            }
        }

        void ReadCallBack(IAsyncResult result)
        {

            try
            {
                RequestState myRequestState = (RequestState)result.AsyncState;
                Stream responseStream = myRequestState.m_streamResponse;
                int read = responseStream.EndRead(result);

                if (read > 0)
                {
                    //将接收的数据写入;
                    //   fileStream.Write(myRequestState.m_bufferRead, 0, 1024);
                    //  fileStream.Flush();
                    //fileStream.Close();

                    //继续读取数据;
                    myRequestState.m_bufferRead = new byte[1024];
                    IAsyncResult asyncreadresult = responseStream.BeginRead(myRequestState.m_bufferRead, 0, 1024, new AsyncCallback(ReadCallBack), myRequestState);
                }
            }
            catch (System.Exception ex)
            {
                Debug.LogError(ex.ToString());
            }
        }




        public delegate void CALLBACK(string name, string url, string datas);
        public CALLBACK onCallBack;

        //状态控制
        public Dictionary<String, int> requeststatus = new Dictionary<String, int>();


        void AsyGet(string name, string url)
        {
            WebRequestData data = new WebRequestData();
            data.httpurl = url;
            data.method = "GET";

            Request(name, data);
        }

        void AsyPost(string name, string url, string datas)
        {
            WebRequestData data = new WebRequestData();
            data.httpurl = url;
            data.method = "POST";
            data.requestDatas = datas;

            Request(name, data);
        }

        /// <summary>
        /// 请求对象
        /// </summary>
        /// <param name="datas"></param>
        /// <returns></returns>
        public IEnumerator ASYPOST(WebRequestData datas)
        {
            requeststatus.Add(datas.name, 0);

            Request(datas.name, datas);

            while (requeststatus[datas.name] == 0)
                yield return null;

            if (requeststatus[datas.name] == 1)
            {
                if (datas.onCallBack != null)
                    datas.onCallBack(datas.name, datas.httpurl, datas);

                if (onCallBack != null)
                    onCallBack(datas.name, datas.httpurl, requests[datas.name].datas);
            }

            requeststatus.Remove(datas.name);
            requests.Remove(datas.name);
        }


        /// <summary>
        /// 使用协程 异步 等待线程返回数据 在内数据才能正常主线程交互，
        /// </summary>
        /// <param name="name"></param>
        /// <param name="url"></param>
        /// <param name="datas"></param>
        /// <returns></returns>
        public IEnumerator ASYPOST(string name, string url, string datas)
        {

            requeststatus.Add(name, 0);

            AsyPost(name, url, datas);

            while (requeststatus[name] == 0)
                yield return null;

            if (requeststatus[name] == 1 && onCallBack != null)
            {
                onCallBack(name, url, requests[name].datas);
            }

            requeststatus.Remove(name);
            requests.Remove(name);
        }


        /// 请求网络数据 使用线程异处理 通过 onCallBack 返回数据 
        ///name 唯一标志  url 地址
        public IEnumerator ASYGET(string name, string url)
        {

            requeststatus.Add(name, 0);

            AsyGet(name, url);

            while (requeststatus[name] == 0)
                yield return null;

            if (requeststatus[name] == 1 && onCallBack != null)
            {
                onCallBack(name, url, requests[name].datas);
            }

            requeststatus.Remove(name);
            requests.Remove(name);

        }


        //请求队列
        public Dictionary<String, WebRequestData> requests = new Dictionary<String, WebRequestData>();

        /// <summary>
        /// 创建线程请求队列
        /// </summary>
        /// <param name="name"></param>
        /// <param name="datas"></param>
        void Request(string name, WebRequestData datas)
        {
            //ParameterizedThreadStart 多线程传参 
            Thread thread = new Thread(new ParameterizedThreadStart(TreadtoRequest));
            thread.IsBackground = true;
            //只能带一个object参数 所以使用字符串拼接
            thread.Start(name);
            datas.requestThread = thread;
            requests.Add(name, datas);
        }

        /// <summary>
        /// 注意在手机上测试 该对Ip地址,不能使用域名
        /// 线程代理请求
        /// </summary>
        /// <param name="file">线程只能中 object </param>
        void TreadtoRequest(System.Object file)
        {

            HttpHelper help = new HttpHelper(requests[file.ToString()]);
            help.onSuccess += requestcallback;
            help.onError += requstcallerror;
            help.AsyncPOST();
        }

        /// <summary>
        /// 网络成功返回
        /// </summary>
        /// <param name="name"></param>
        /// <param name="datas"></param>
        void requestcallback(string name, WebRequestData datas)
        {
            datas.requestThread.Abort();
            //  Debug.Log("net callback:" + datas.datas);
            requeststatus[name] = 1;

        }

        /// <summary>
        /// 网络返回错误
        /// </summary>
        /// <param name="name"></param>
        /// <param name="message"></param>
        void requstcallerror(string name, string message)
        {
            requests[name].requestThread.Abort();
            //Debug.LogError("net " + name + message);
            requeststatus[name] = 2;
        }



    }
}